package com.code2roc.fastboot.framework.quartz;

import com.code2roc.fastboot.FastBootApplication;
import com.code2roc.fastboot.framework.util.BeanUtil;
import com.code2roc.fastboot.framework.util.ScanUtil;
import org.quartz.*;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;

@Component
public class QuartzUtil {
    private static String JOB_GROUP_NAME = "DEFAULT_JOB_GROUP_NAME";
    private static String TRIGGER_GROUP_NAME = "DEFAULT_TRIGGER_GROUP_NAME";
    private static List<QuartzTaskJobInfo> jobInfoList = new ArrayList<>();

    //增加定时任务任务
    public void addIntervalJob(String jobName, Class<? extends Job> cls, int peroid, int timeUnit) {
        try {
            SchedulerFactoryBean schedulerFactoryBean = BeanUtil.getBean(SchedulerFactoryBean.class);
            SimpleScheduleBuilder scheduleBuilder = null;
            if (timeUnit == QuartzEnum.ExecuteUnit.Second.get_value()) {
                scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInSeconds(peroid).repeatForever();
            } else if (timeUnit == QuartzEnum.ExecuteUnit.Minute.get_value()) {
                scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInMinutes(peroid).repeatForever();
            } else if (timeUnit == QuartzEnum.ExecuteUnit.Hour.get_value()) {
                scheduleBuilder = SimpleScheduleBuilder.simpleSchedule().withIntervalInHours(peroid).repeatForever();
            }
            Scheduler sched = schedulerFactoryBean.getScheduler();
            JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).storeDurably().build();
            Trigger trigger = TriggerBuilder.newTrigger().forJob(jobDetail).withIdentity(jobName, TRIGGER_GROUP_NAME).withSchedule(scheduleBuilder).build();

            sched.scheduleJob(jobDetail, trigger);
            if (!sched.isShutdown()) {
                sched.start();        // 启动
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //增加corn表达式任务
    public void addCornJob(String jobName, Class<? extends Job> cls, String cornExpress) {
        try {
            SchedulerFactoryBean schedulerFactoryBean = BeanUtil.getBean(SchedulerFactoryBean.class);
            Scheduler sched = schedulerFactoryBean.getScheduler();
            JobDetail jobDetail = JobBuilder.newJob(cls).withIdentity(jobName, JOB_GROUP_NAME).build();
            CronTrigger trigger = (CronTrigger) TriggerBuilder
                    .newTrigger()
                    .withIdentity(jobName, TRIGGER_GROUP_NAME)
                    .withSchedule(CronScheduleBuilder.cronSchedule(cornExpress))
                    .build();
            sched.scheduleJob(jobDetail, trigger);
            if (!sched.isShutdown()) {
                sched.start();        // 启动
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    //停止任务
    public void deleteJob(String jobName) {
        try {
            SchedulerFactoryBean schedulerFactoryBean = BeanUtil.getBean(SchedulerFactoryBean.class);
            Scheduler sched = schedulerFactoryBean.getScheduler();
            TriggerKey triggerKey = TriggerKey.triggerKey(jobName, TRIGGER_GROUP_NAME);
            JobKey jobKey = JobKey.jobKey(jobName, JOB_GROUP_NAME);
            sched.pauseTrigger(triggerKey); // 停止触发器
            sched.unscheduleJob(triggerKey);// 移除触发器
            sched.deleteJob(jobKey);        // 删除任务
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void executeOnce(String jobName,Class<? extends Job> cls) throws Exception{
        Job jobInstance = BeanUtil.getBean(cls);
        SchedulerFactoryBean schedulerFactoryBean = BeanUtil.getBean(SchedulerFactoryBean.class);
        Scheduler sched = schedulerFactoryBean.getScheduler();
        JobExecutionContext context = new CustomerJobExecutionContext(sched,jobName);
        jobInstance.execute(context);
    }

    public void initQuartzJob(Class runtimeClass) {
        jobInfoList.clear();
        List<Class<?>> taskJobClass = ScanUtil.getAllClassByPackageName_Annotation(runtimeClass.getPackage(), QuartzTaskJob.class);
        if (!runtimeClass.getPackage().getName().equals(FastBootApplication.class.getPackage().getName())) {
            taskJobClass.addAll(ScanUtil.getAllClassByPackageName_Annotation(FastBootApplication.class.getPackage(),  QuartzTaskJob.class));
        }
        for (Class clazz : taskJobClass) {
            QuartzTaskJobInfo jobInfo = new QuartzTaskJobInfo();
            QuartzTaskJob quartzTaskJob = (QuartzTaskJob)clazz.getAnnotation(QuartzTaskJob.class);
            jobInfo.setJob_name(quartzTaskJob.remark());
            jobInfo.setJob_class_path(clazz.getName());
            jobInfoList.add(jobInfo);
        }
    }

    public static List<QuartzTaskJobInfo> getJobInfoList() {
        return jobInfoList;
    }
}
